import { ChunkEntityType, ChunkEntityUpdateType } from "../../GameDef";
import CmpTrans from "../../lib/kgame/ecs/CmpTrans";
import { ECSScene } from "../../lib/kgame/ecs/ECSScene";
import { IVec2 } from "../../lib/kgame/util/Defined";
import { CmpAI } from "../cmp/CmpAI";
import { CmpChunkEntity } from "../cmp/CmpChunkEntity";
import { CmpMove } from "../cmp/CmpMove";
import { CmpSnake } from "../cmp/CmpSnake";
import { CmpSnakeBody } from "../cmp/CmpSnakeBody";
import { CmpSnakeHead } from "../cmp/CmpSnakeHead";
import { AISnake } from "../cmp/ai/AISnake";
import { SCmpWorld } from "../scmp/SCmpWorld";

/**
 * 蛇创建
 */
export class SnakeFactory {

    /**
     * 创建蛇
     * @param scene 场景
     * @param snakeId 蛇id
     */
    static createSnake(scene: ECSScene, name: string) {
        const entity = scene.createEntity();
        const snakeId = scene.getCmp(SCmpWorld).getSnakeId();
        const snake = entity.createCmp(CmpSnake).onCreate(snakeId, name);
        entity.createCmp(CmpTrans);
        entity.apply();
        return snake;
    }

    /**
     * 创建ai蛇
     * @param scene 场景
     * @param snakeId 蛇id
     */
    static createAiSnake(scene: ECSScene) {
        const snake = this.createSnake(scene, scene.getCmp(SCmpWorld).getAIName());
        snake.entity.createCmp(CmpAI).onCreate(new AISnake(snake));
        return snake;
    }

    /**
     * 创建蛇头
     * @param snake 蛇组件
     */
    static createHead(snake: CmpSnake) {
        const entity = snake.scene.createEntity();
        entity.pos.setPosTo(snake.pos);
        const trans = entity.createCmp(CmpTrans);
        trans.rot = snake.trans.rot;

        const head = entity.createCmp(CmpSnakeHead);
        head.onCreate(snake, entity.createCmp(CmpMove).onCreate(trans.rot));

        return head;
    }

    /**
     * 创建蛇身
     * @param head 蛇头组件
     */
    static createBody(head: CmpSnakeHead, pos?: IVec2) {
        const idx = head.bodys.length;
        const entity = idx === 0 ? head.entity : head.scene.createEntity();
        const body = entity.createCmp(CmpSnakeBody);
        if (!body.entity.hasCmp(CmpTrans)) {
            body.entity.createCmp(CmpTrans);
        }

        const last = head.tail;
        head.bodys.push(body.onCreate(head));

        if (idx === 0) {
            body.pos.setPosTo(pos);
            body.trans.rot = head.trans.rot;
        } else {
            if (pos) {
                head.pathTail.next = { x: pos.x, y: pos.y, rot: last.trans.rot };
            }
            body.pos.setPosTo(pos || last.pos);
            body.trans.rot = last.trans.rot;
        }

        entity.createCmp(CmpChunkEntity).onCreate(ChunkEntityType.snakeBody, ChunkEntityUpdateType.update, body.collider.worldAABB);
        return body;
    }

}